//
//  CoGeMissingsSearchController.m
//  CoGeOpenSource
//
//  Created by Tamas Nagy on 5/10/11.
//  Copyright 2011 home. All rights reserved.
//

#import "CoGeMissingsSearchController.h"


@implementation CoGeMissingsSearchController

@synthesize window;
@synthesize theTableView;
@synthesize progressIndicator;
@synthesize currentLabel;
@synthesize missingsDict;
@synthesize needsSkip;
@synthesize searchStarted;
@synthesize origDict;
@synthesize searchScopes;
@synthesize spotlightSearchButton;
@synthesize modalSession;

- (id)init
{
    self = [super init];
    if (self) {
        [theTableView setDelegate:self];
        self.missingsDict = [[NSDictionary alloc] init];
        self.origDict = [[NSMutableDictionary alloc] init];
        
        //the app directory
        NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
        NSMutableArray *pathArray = [NSMutableArray arrayWithArray:[bundlePath componentsSeparatedByString:@"/"]];
        [pathArray removeLastObject];

        self.searchScopes = [[CoGeThreadSafeMutableArray alloc] initWithObjects:[pathArray componentsJoinedByString:@"/"], NSMetadataQueryUserHomeScope, NSMetadataQueryLocalComputerScope, nil];
    }
    
    return self;
}

- (void)dealloc
{
    [theTableView setDelegate:nil];
    [missingsDict release];
    [origDict release];
    [searchScopes release];
    [super dealloc];
}

#pragma mark Checking

-(BOOL)checkDictionary:(NSDictionary *)dict {
    
    NSLog(@"start search for missing files...");
    
    [[dict retain] autorelease];

    NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
    
    self.origDict = [[NSMutableDictionary alloc] initWithDictionary:dict];
    
    NSFileManager *fMan = [NSFileManager defaultManager];
    
    for (NSString *aKey in dict) {
        
        //search for NSString and subclasses only
        if ([[[self.origDict objectForKey:aKey] class] isSubclassOfClass:[NSString class]]) {
            
            if ((![[self.origDict objectForKey:aKey] isEqualToString:@""]) && (![fMan fileExistsAtPath:[self.origDict objectForKey:aKey]])) {
                
                [tempDict setObject:[self.origDict objectForKey:aKey] forKey:aKey];
                
            } 
                
        }
        
    }
    
    self.missingsDict = [[NSDictionary alloc] initWithDictionary:tempDict];
    [tempDict release];
    if ([self.missingsDict count]>0) {
        NSLog(@"... found missing files!");
        [self.theTableView reloadData];
        self.modalSession = [NSApp beginModalSessionForWindow:self.window];
        [self.theTableView reloadData];
        return YES;
    } else {
        NSLog(@"... no missing files");
        NSDictionary *returnDict = [[NSDictionary alloc] initWithDictionary:self.origDict];
        self.origDict = nil;
        
        [[NSNotificationCenter defaultCenter] postNotificationName:@"SpotlightSearchFinished" object:[returnDict autorelease]];

        return NO;
    }

}

#pragma mark Searching


-(void)spotlightSearchForFiles {
    
    NSMetadataQuery *query = nil;
    
    [self.progressIndicator startAnimation:self];
    
    self.searchStarted = YES;
    
    for (NSString *aKey in self.missingsDict) {
                
        query = [[NSMetadataQuery alloc] init];
                
        [query setSearchScopes:self.searchScopes];
        
        NSString *currentsearch = [[self.missingsDict objectForKey:aKey] lastPathComponent];
        
        NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"kMDItemFSName == '%@'", currentsearch]];
                 
        [query setPredicate:predicate];
        
        if ([query startQuery])  {
            [[self.currentLabel cell] setTitle:[NSString stringWithFormat:@"Please wait, searching for: %@", currentsearch]];
            while (([query isGathering] && !self.needsSkip) && ([[query results] count] == 0))  {
                [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
            }
        }
        
        if (self.needsSkip) {
            [[currentLabel cell] setTitle:@"Search skipped."];
            [query stopQuery];
            [query release];
            
            
            break;
        }
        
        if ([query resultCount]>0) {
            [self.origDict setObject:[[query resultAtIndex:0] valueForAttribute:@"kMDItemPath"] forKey:aKey];
            [theTableView reloadData];

        }
        
        [query stopQuery];
        [query release];
    }
    
    [self.progressIndicator stopAnimation:self];
    [[self.currentLabel cell] setTitle:@""];
        
    [self.theTableView reloadData];
    
    self.needsSkip = NO;
    self.searchStarted = NO;
    [self.spotlightSearchButton setEnabled:YES];
}



#pragma mark Skipping

-(IBAction)skipSpotlightSearch:(id)sender {
    
    if (!self.searchStarted) {
        
        //removes all the missing keys
        for (NSString *removeKey in self.missingsDict) {
            [self.origDict setObject:[NSString stringWithString:@""] forKey:removeKey];
        }
        
        NSDictionary *returnDict = [[NSDictionary alloc] initWithDictionary:self.origDict];
        self.origDict = nil;

        [NSApp endModalSession:self.modalSession];
        [self.window orderOut:self];

        [[NSNotificationCenter defaultCenter] postNotificationName:@"SpotlightSearchFinished" object:[returnDict autorelease]];
        

        

    } else {
        self.needsSkip = YES;
        
        [self.spotlightSearchButton setEnabled:YES];

    }


    
}

-(IBAction)doneSearch:(id)sender {
    
    if (!self.searchStarted) {

    } else {
        self.needsSkip = YES;
    }

    NSDictionary *returnDict = [[NSDictionary alloc] initWithDictionary:self.origDict];
    self.origDict = nil;

    [NSApp endModalSession:self.modalSession];
    [self.window orderOut:self];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"SpotlightSearchFinished" object:[returnDict autorelease]];


    
}


#pragma mark Actions

-(void)manualLocate:(id)sender {
    
    NSOpenPanel *oPanel = [NSOpenPanel openPanel];
	
	NSInteger returnCode = [oPanel runModalForDirectory:nil file:nil types:nil];
	
	if (returnCode == NSOKButton) {
		
		NSArray *urls = [oPanel URLs];
		
		[self.origDict setObject:[[urls objectAtIndex:0] path] forKey:[[self.missingsDict allKeys] objectAtIndex:[theTableView selectedRow]]];
		
        [theTableView reloadData];
	}

    
}

-(IBAction)searchWithSpotlight:(id)sender {
    
    self.needsSkip = NO;
    
    [self.spotlightSearchButton setEnabled:NO];
    
    [NSThread detachNewThreadSelector:@selector(startSearchOnThread) toTarget:self withObject:nil];
    
}


-(void)startSearchOnThread {
    
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    [self performSelector:@selector(spotlightSearchForFiles)];
    
    [pool release];
}


#pragma mark TableView delegates

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView{
	
	
	return [self.missingsDict count];
	
}

- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
	
    if (([[self.missingsDict allValues] count] == 0) || ([[self.origDict allValues] count] == 0)) {
        return nil;
    }
    
    if ([[tableColumn identifier] intValue] == 0) {
        return [[[self.missingsDict allValues] objectAtIndex:row] lastPathComponent];
    }
 
    if ([[tableColumn identifier] intValue] == 1) {
        return [[self.missingsDict allValues] objectAtIndex:row];
    }

    if ([[tableColumn identifier] intValue] == 2) {
        
        if ([[self.origDict objectForKey:[[self.missingsDict allKeys] objectAtIndex:row]] isEqualTo:[[self.missingsDict allValues] objectAtIndex:row]]) {
            return nil;
        
        } else {
            return [self.origDict objectForKey:[[self.missingsDict allKeys] objectAtIndex:row]];
        }
        
        
    }

    if ([[tableColumn identifier] intValue] == 3) {
        NSButtonCell *theCell = [tableColumn dataCellForRow:row];
        [theCell setTarget:self];
        [theCell setAction:@selector(manualLocate:)];
        return theCell;
        
    }
    
    return nil;
    
}



@end
